﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;


namespace CCPSIP
{
  public class SmsKit
  {
    private static string[] countryCodeArray = { "+886", "886" };
    private static WebProxy DefaultProxy = new WebProxy("203.69.132.67", 8080);

    private const string kHiAirSvrAddr = "api.hiair.hinet.net";
    private const string kHiAirSvrPort = "8000";
    private const string kHiAirUserID = "89938676";
    private static byte[] kHiAirKey = { 0x66, 0x37, 0x38, 0x36, 0x66, 0x35, 0x34, 0x63 };

    private const string kSmsgoServiceURL = "https://ssl.smsgo.com.tw/sms_gw/sendsms.aspx";
    private const string kSmsgoUsername = "ccpapps@gmail.com";
    private static byte[] kSmsgoKey = { 0x59, 0x50, 0x4E, 0X35, 0X4B,
                                        0X7A, 0X36, 0X36, 0X4A, 0X4D };


    /// <summary>
    /// 使用 SMSGO API 發送簡訊 (v4.2)
    /// </summary>
    /// <param name="MobileNum">手機門號</param>
    /// <param name="Message">簡訊內容</param>
    /// <returns>若發送成功，回傳SMSGO訊息代號；否則null</returns>
    public static string SendSmsgoSMS(string MobileNum, string Message) {
      const int kRespMaxKB = 3;//in KB

      MobileNum = trimCountryCode(MobileNum);
      if (!Regex.IsMatch(MobileNum, "^09[0-9]{8}$")) {
        if (!MobileNum.StartsWith("+"))
          MobileNum = "+" + MobileNum;//國際門號前面要加"+"
      }

      //【01】組合 GET Request URL
      //
      Dictionary<string, string> paramDict = new Dictionary<string, string>();
      paramDict["username"] = kSmsgoUsername;
      paramDict["password"] = Encoding.UTF8.GetString(kSmsgoKey);
      paramDict["dstaddr"] = MobileNum;
      paramDict["smbody"] = Message;
      string queryStr = ChrisKit.DictToQueryStr(paramDict, Encoding.UTF8);
      string reqURL = string.Format("{0}?{1}", kSmsgoServiceURL, queryStr);

      //【02】Generate Web Request
      //
      HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(reqURL);
      ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
      webReq.ProtocolVersion = HttpVersion.Version11;
      webReq.Method = "GET";
      webReq.Timeout = 30 * 1000;
      webReq.KeepAlive = false;
      webReq.AllowAutoRedirect = false;
      webReq.Proxy = DefaultProxy;

      //【03】Get the response
      //
      HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse();
      System.IO.Stream respStream = webResp.GetResponseStream();

      byte[] respBytes = new byte[kRespMaxKB * 1024];
      int bytesCount = 0;

      for (int i = 0; i < kRespMaxKB; i++) {
        int readCount = respStream.Read(respBytes, bytesCount, 1024);
        if (readCount == 0)
          break;
        else
          bytesCount += readCount;
      }

      // Cleanup
      respStream.Close();
      webResp.Close();

      string respStr = Encoding.UTF8.GetString(respBytes, 0, bytesCount);
      Dictionary<string, string> respDict = ChrisKit.DictFromKVStr(respStr, "\r\n");
      return (respDict.ContainsKey("msgid") ? respDict["msgid"] : null);
    }



    #region 中華電信 IMSP 服務

    //private const string kImspUrl = "http://imsp.emome.net:8008/imsp/sms/servlet/SubmitSM";
    //private const string kImspAccount = "10658";
    //private const string kImspPassword = "10658";
    //private const string kImspSenderNo = "0911510658";
    //public const string kReceiverSeparator = ",";

    ///// <summary>
    ///// 使用中華電信IMSP服務發送SMS簡訊
    ///// </summary>
    ///// <param name="receivers">收件人號碼</param>
    ///// <param name="message">簡訊內容</param>
    ///// <returns>IMSP服務Response字串</returns>
    //public static string[] SendEmomeIMSP(string receivers, string message) {
    //  if (receivers.EndsWith(kReceiverSeparator)) {
    //    receivers = receivers.Remove(receivers.Length - kReceiverSeparator.Length);
    //  }

    //  Dictionary<string, string> paramDict = new Dictionary<string, string>();
    //  paramDict["account"] = kImspAccount;
    //  paramDict["password"] = kImspPassword;
    //  paramDict["from_addr_type"] = "0";
    //  paramDict["from_addr"] = kImspSenderNo;
    //  paramDict["to_addr_type"] = "0";
    //  paramDict["to_addr"] = receivers;

    //  if (Regex.IsMatch(message, @"[^\u0000-\u007F]")) {
    //    paramDict["msg_type"] = "2";
    //    byte[] msgBytes = Encoding.BigEndianUnicode.GetBytes(message);
    //    paramDict["msg"] = ChrisKit.getHexStr(msgBytes, false);
    //  }
    //  else {
    //    paramDict["msg_type"] = "0";
    //    paramDict["msg"] = message;
    //  }

    //  string paramStr = Kit.ChrisKit.DictToPostStr(paramDict, Encoding.UTF8);
    //  byte[] postBytes = Encoding.UTF8.GetBytes(paramStr);

    //  string imspResponse = "";
    //  for (int i = 0; i < 3; i++) {
    //    if (i > 0) {
    //      // 第二次以後，先等待一下再傳送
    //      System.Threading.Thread.Sleep(5 * 1000);
    //    }

    //    try {
    //      // Send to emome IMSP Service
    //      //
    //      HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(kImspUrl);
    //      webReq.ProtocolVersion = HttpVersion.Version11;
    //      webReq.Method = "POST";
    //      webReq.Timeout = 30 * 1000;
    //      webReq.KeepAlive = false;
    //      webReq.AllowAutoRedirect = false;
    //      webReq.Proxy = DefaultProxy;

    //      webReq.ContentType = "application/x-www-form-urlencoded";
    //      webReq.ContentLength = postBytes.Length;
    //      using (System.IO.Stream reqStream = webReq.GetRequestStream()) {
    //        reqStream.Write(postBytes, 0, postBytes.Length);
    //        reqStream.Flush();
    //        reqStream.Close();
    //      }

    //      HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse();
    //      System.IO.Stream respStream = webResp.GetResponseStream();
    //      System.IO.StreamReader reader = new System.IO.StreamReader(respStream);
    //      imspResponse = reader.ReadToEnd();

    //      // Cleanup
    //      reader.Close();
    //      respStream.Close();
    //      webResp.Close();

    //      break;
    //    }
    //    catch (Exception ex) {
    //    }
    //  }
    //  return extractResp(imspResponse);
    //}


    ///// <summary>
    ///// Extract response message from response HTML
    ///// </summary>
    ///// <param name="imspResp">IMSP response HTML</param>
    ///// <returns>response message</returns>
    //private static string[] extractResp(string imspResp) {
    //  if (imspResp.IndexOf("</body>") > 0) {
    //    int startIndex = imspResp.IndexOf("<body>") + 6;
    //    int endIndex = imspResp.IndexOf("</body>") - 1;
    //    int respLength = endIndex - startIndex;
    //    string respStr = imspResp.Substring(startIndex, respLength);

    //    string[] separator = { "<br>" };
    //    string[] respArray = respStr.Split(separator, StringSplitOptions.RemoveEmptyEntries);
    //    for (int i = 0; i < respArray.Length; i++) {
    //      respArray[i] = respArray[i].Trim();
    //    }
    //    return respArray;
    //  }
    //  else {
    //    string[] respArray = new string[1];
    //    respArray[0] = imspResp;
    //    return respArray;
    //  }
    //}

    #endregion



    #region 中華電信 HiAir 服務


    /// <summary>
    /// 使用中華電信HiAir服務發送SMS簡訊
    /// </summary>
    /// <param name="MobileNum">收訊方手機門號</param>
    /// <param name="Message">SMS簡訊內容</param>
    /// <returns>呼叫成功回傳HiAir MessageID，否則null</returns>
    public static string SendHiAirSMS(string MobileNum, string Message) {
      string respMsg = null;
      MobileNum = trimCountryCode(MobileNum);
      if (!Regex.IsMatch(MobileNum, "^09[0-9]{8}$")) {
        if (!MobileNum.StartsWith("+"))
          MobileNum = "+" + MobileNum;//國際門號前面要加"+"
      }

      HiAirLib.HiNetSMSClass smsObj = new HiAirLib.HiNetSMSClass();
      string tempKey = Encoding.UTF8.GetString(kHiAirKey);
      short statusCode = smsObj.StartCon(kHiAirSvrAddr, kHiAirSvrPort, kHiAirUserID, tempKey);
      if (statusCode == 0) {
        statusCode = smsObj.SendMsg(MobileNum, Message);
        respMsg = smsObj.Get_Message();
        smsObj.EndCon();
      }
      return respMsg;
    }


    /// <summary>
    /// 查詢中華電信HiAir服務傳送結果
    /// </summary>
    /// <param name="MessageID">HiAir MessageID</param>
    /// <returns>HiAir服務傳送結果，Key=ret_code，Value=ret_content</returns>
    public static KeyValuePair<short, string>? QueryHiAirSMS(string MessageID) {
      try {
        HiAirLib.HiNetSMSClass smsObj = new HiAirLib.HiNetSMSClass();
        string tempKey = Encoding.UTF8.GetString(kHiAirKey);
        short statusCode = smsObj.StartCon(kHiAirSvrAddr, kHiAirSvrPort, kHiAirUserID, tempKey);
        if (statusCode == 0) {
          statusCode = smsObj.QueryMsg(MessageID);
          string statusDesc = smsObj.Get_Message();
          smsObj.EndCon();
          return new KeyValuePair<short, string>(statusCode, statusDesc);
        }
      }
      catch {
      }
      return null;
    }


    #endregion



    /// <summary>
    /// 把電話號碼開頭的國碼替換為"0"
    /// </summary>
    /// <param name="phoneNumber">國際電話號碼(如+886933123456)</param>
    /// <returns>替換國碼後的電話號碼</returns>
    public static string trimCountryCode(string phoneNumber) {
      if (phoneNumber.Length >= 12) {
        foreach (string countryCode in countryCodeArray) {
          if (phoneNumber.StartsWith(countryCode))
            return "0" + phoneNumber.Substring(countryCode.Length);
        }
      }
      return phoneNumber;
    }


  }
}